<template>
  <div id="threeBox" ref="threeBox"></div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import * as Three from "three";
import { OrbitControls } from "three/examples/jsm/Addons.js";
console.log("🚀 ~ Three:", Three.Scene);

const threeBox = ref();

const initThree = (el) => {
  // 创建场景
  const scene = new Three.Scene();
  // 创建摄像机
  const camera = new Three.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    2000
  ); // （角度  ， 长宽比  ， 视口最近距离， 视口最远距离）
  camera.position.x = -30;
  camera.position.y = 30;
  camera.position.z = 30;
  camera.lookAt(scene.position); // 将摄像机放入场景

  // 创建渲染器（画布）
  const renderer = new Three.WebGLRenderer();
  renderer.setClearColor(0xeeeeee); // 设置画布颜色
  renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小

  const axes = new Three.AxesHelper(30); // 坐标系的长度
  scene.add(axes); // 将坐标添加到场景中

  // 创建地面
  const planeGeometry = new Three.PlaneGeometry(60, 20); // 创建地面的大小
  const planeMaterial = new Three.MeshStandardMaterial({ color: 0x999999 }); //地面的材质
  const plane = new Three.Mesh(planeGeometry, planeMaterial); // 创建地面
  plane.rotation.x = -0.5 * Math.PI; // 旋转角度
  plane.position.x = 15; // 设置地面 xyz 轴的位置
  plane.position.y = 0;
  plane.position.z = 0;
  scene.add(plane); // 将地面添加到坐标轴中
  plane.receiveShadow = true;   //地面被投影

  // 创建立方体
  let cubeGeometry = new Three.BoxGeometry(4, 4, 4); //长宽高
  let cubeMaterial = new Three.MeshLambertMaterial({ color: 'red' }); //材质颜色
  let cube = new Three.Mesh(cubeGeometry, cubeMaterial);
  cube.position.x = 3; //三轴的位置
  cube.position.y = 8;
  cube.position.z = 3;
  scene.add(cube);
  cube.castShadow = true;    //立方体投影

  // 创建球体
  let sphereGeometry = new Three.SphereGeometry(2,20,20); //半径，圆滑程度
  let sphereMaterial = new Three.MeshLambertMaterial({ color: 'blue' }); //材质颜色
  let sphere = new Three.Mesh(sphereGeometry,sphereMaterial);
  sphere.position.x = 12; //三轴的位置
  sphere.position.y = 4;
  sphere.position.z = 4;
  scene.add(sphere);
  sphere.castShadow = true;  //球投影


  // 添加聚光灯
  let point = new Three.SpotLight(0xffffff);  //设置灯光的颜色
  point.position.set(80, 100, 80); //点光源位置
  point.intensity = 20000;//将光照强度直接拉到20000
  point.angle = Math.PI/10;  //设置投影的程度
  point.shadow.mapSize.set(1024,1024);
  scene.add(point);
  point.castShadow = true;   //灯光投影

  renderer.shadowMap.enabled=true;  //让渲染器支持投影

  el.appendChild(renderer.domElement); // // 将这个canvas元素插入到 html中
  renderer.render(scene, camera);

  // 实现鼠标控制视角
  let controls = new OrbitControls(camera,renderer.domElement);
    controls.addEventListener('change',()=>{
    	renderer.render(scene, camera);
	});
};

onMounted(() => {
  if (threeBox) {
    initThree(threeBox.value);
  }
});
</script>
<style scoped></style>
